在開發後端應用程式時,資料驗證和中間件的設計是非常重要的。這不僅能確保資料的正確性,也能提升 API 的穩定性。在這篇文章中,我們將使用與 TypeScript 很搭的 Zod 進行資料驗證,並撰寫一個簡單的 Express 中間件來處理錯誤。
Zod 是一個功能強大的 TypeScript 驗證套件,它允許我們用簡潔的語法來定義資料結構和約束。相比其他驗證庫,Zod 更加貼合 TypeScript 的型別系統,並且支援推斷型別。這讓我們能夠從 Schema 中自動生成 TypeScript 型別,減少重複代碼。更多資訊可以查看 Zod 的文檔
首先我們安裝 Zod
npm i zod
在這裡,我們使用 Zod 來驗證我們要存的 Task 資料。Task 包含以下幾個欄位:標題、描述、狀態、以及預估的 Story Point。透過 z.object
定義一個 Zod Schema,並利用 z.infer
的方式來生成對應的 TypeScript 型別。
import { z } from 'zod';
// ...
export const inputTaskSchema = z.object({
title: z.string().min(1),
description: z.string().optional(),
status: z.enum(['new', 'active', 'completed']).default('new'),
storyPoint: z.number().optional(),
});
export interface TaskType extends z.infer<typeof inputTaskSchema> {
id: string;
}
export default class TaskModel extends AbstractBaseModel<TaskType> {
collection = 'task';
validateData(data: unknown): z.infer<typeof inputTaskSchema> {
return inputTaskSchema.parse(data);
}
}
接下來,我們在 Controller 撰寫一個 createTask
函式,負責新增一個 Task。這裡透過 taskModel.validateData
來驗證傳入的資料,確保資料符合 Schema
的約束。
// ...
export const createTask = async (
req: Request<{}, {}, TaskType>,
res: Response<{ id: string }>,
next: NextFunction
) => {
try {
const task = taskModel.validateData(req.body);
const id = await taskModel.create(task);
res.status(201).json({ id });
} catch (error) {
next(error);
}
};
在 Express 中,中間件(middleware)是處理請求和響應的一個重要組件,通過 use
調用,可以在請求處理的不同階段插入特定邏輯。
以下是三個都是中間件:
express.json
是 Express 提供的中間件,使用 express.json()
來解析 req.body
傳入的 JSON 請求。import express, { NextFunction, Request, Response } from 'express';
import { ZodError } from 'zod';
// ...
class Server {
// ...
start() {
this.app.use(express.json());
this.app.use('/task', taskRouter);
this.app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof ZodError) {
res.status(400).json({ message: err.errors });
} else {
res.status(500).json({ message: err.message });
}
next();
});
this.app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
}
}
// ...
我們可以使用 REST Client 工具來測試 API,將資料傳送至後端並驗證其是否新增成功。
若操作成功,可以在 db.json 檔案中檢查是否有新的 Task 被新增。
這篇文章展示了如何透過 Zod 進行資料驗證,並撰寫 Express 的中間件來處理驗證錯誤。我們也撰寫完新增的邏輯,後面編輯與刪除的邏輯也是差不多的寫法,後端的部分大致上已經差不多了,下一篇我會介紹如何利用 TypeScript 5 新的裝飾器來重構我們的 Controller,並讓架構更精簡。
本篇程式碼變更可以看此 PR